package utils;

/**
 * Created by fanzhenyu02 on 2020/2/14.
 */

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;


public class ProcessWxLog {


    public static void run_analysis_bizMerchantNo() {
        Map<String, StringBuilder> map = new TreeMap<>();
        String line = null;
        try {
            FileInputStream inputStream = new FileInputStream("/Users/vonmax/Downloads/paygate_info.log-2020-05-22-2.log");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

            while ((line = bufferedReader.readLine()) != null) {
                try {
                    String traceId = line.split("__traceId__=")[1].split("}#")[0];
                    if (map.containsKey(traceId)) {
                        StringBuilder builder = map.get(traceId);
                        builder.append(line).append("\n");
                    } else {
                        StringBuilder builder = new StringBuilder();
                        builder.append(line).append("\n");
                        map.put(traceId, builder);
                    }
                } catch (Exception e) {
                    //System.out.println("Skipp line :"+line);
                }
            }

//            FileOutputStream outputStream = new FileOutputStream("/Users/vonmax/Downloads/logMap.txt");
//            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
//            bufferedWriter.write(map.toString());
//            outputStream.close();
//            bufferedWriter.close();


            Map<String, Set<String>> bizMap = new TreeMap<>();
            for (Map.Entry<String, StringBuilder> entry : map.entrySet()) {
                String logContent = entry.getValue().toString();
                try {
                    String key = logContent.split("验签字符串为:")[1].split("2020-")[0];
                    if (logContent.contains("bizMerchantNo=")) {
                        key = logContent.split("bizMerchantNo=")[1].split("&")[0];
                    }
                    String appId = getAppIdFromLog(logContent);

                    if (bizMap.containsKey(key)) {
                        bizMap.get(key).add(appId);
                    } else {
                        Set<String> appIdSet = new HashSet<>();
                        appIdSet.add(appId);
                        bizMap.put(key, appIdSet);
                    }
                } catch (Exception ex) {
                    System.out.println("Exception parse traceId: " + entry.getKey());
//                    System.out.println("error parse log: " + logContent);
                }
            }

            System.out.println("开始打印map\n\n");
            printMap(bizMap, "analysis.txt");

            //close stream
            inputStream.close();
            bufferedReader.close();
        } catch (Exception e) {
            System.out.println(line);
            e.printStackTrace();
        }
    }

    public static String getAppIdFromLog(String logContent) {
        String appId = "";

        // method 1
        try {
            appId = logContent.split("\"appid\":\"")[1].split("\",\"")[0];
        } catch (Exception e) {

        }
        if (StringUtils.isNotBlank(appId)) {
            return appId;
        }

        // method 2
        try {
            appId = logContent.split("<appid><!")[1].split("]]>")[0].split("CDATA\\[")[1];
        } catch (Exception e) {

        }
        if (StringUtils.isNotBlank(appId)) {
            return appId;
        }

        // method 3
        try {
            appId = logContent.split("appid")[1].split(",|&")[0];
            appId = appId.substring(appId.indexOf("wx"));
        } catch (Exception e) {

        }
        if (StringUtils.isNotBlank(appId)) {
            return appId;
        }


        return appId;
    }


    public static void printMap(Map<String, Set<String>> resMa, String fileName) throws Exception {
        FileOutputStream outputStream = new FileOutputStream("/Users/vonmax/Downloads/" + fileName);
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));

        for (Map.Entry<String, Set<String>> entry : resMa.entrySet()) {
//            if (!entry.getKey().contains("=") && !entry.getKey().contains("&")) {
//                System.out.println("--------------------------------------------------------");
//                System.out.println(entry.getKey() + " -> value: " + entry.getValue().toString());
//            }

            bufferedWriter.write(entry.getKey() + " -> value: " + entry.getValue().toString() + "\n\n");

        }

        bufferedWriter.close();
        outputStream.close();
    }

    public static Map<String, String> extractKeyParam(String param) {
        List<String> paramList = Arrays.asList(param.split("&"));
        Map<String, String> paramMap = new HashMap<>();
        for (String pa : paramList) {
            String[] paArr = pa.split("=");
            String key = paArr[0];
            String value = paArr.length >= 2 ? paArr[1] : "";
            if (key.equals("payType") || key.equals("payMode") || key.equals("appName") || key.equals("merchantId") ||
                    key.equals("subMerchantId") || key.equals("bizMerchantNo") || key.equals("bizSubMerchantNo")
                    || key.equals("appId")) {
                paramMap.put(key, value);
            }
        }

        return paramMap;
    }

    public static Map<String, String> extractConfKeyParam(String param) {
        Map<String, String> paramMap = JsonUtil.readValue(param, Map.class);
        Map<String, String> retMap = new LinkedHashMap<>();
        retMap.put("payMode", paramMap.get("payMode"));
        retMap.put("appName", paramMap.get("appName"));
        retMap.put("notifyKey", paramMap.get("notifyKey"));
        retMap.put("auxiliaryAttribute", paramMap.get("auxiliaryAttribute"));

        return retMap;
    }

    public static void run_analysis_wxMerchantId() throws Exception {
        // start to load file to memory
        Map<String, StringBuilder> map = new TreeMap<>();
        String line = null;
        try {
            FileInputStream inputStream = new FileInputStream("/Users/vonmax/Downloads/paygate_info.log_aaaa");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

            while ((line = bufferedReader.readLine()) != null) {
                try {
                    String traceId = line.split("__traceId__=")[1].split("}#")[0];
                    if (map.containsKey(traceId)) {
                        StringBuilder builder = map.get(traceId);
                        builder.append(line).append("\n");
                    } else {
                        StringBuilder builder = new StringBuilder();
                        builder.append(line).append("\n");
                        map.put(traceId, builder);
                    }
                } catch (Exception e) {
                    //System.out.println("Skipp line :"+line);
                }
            }

            //close stream
            inputStream.close();
            bufferedReader.close();
        } catch (Exception e) {
            System.out.println(line);
            e.printStackTrace();
        }

        // start to analysis log
        Set<String> resultSet = new HashSet<>();
        List<List<String>> resultList = new ArrayList<>();


        for (Map.Entry<String, StringBuilder> entry : map.entrySet()) {
            String logContent = entry.getValue().toString();
            try {
                if (!logContent.contains("验签字符串为:")) {
                    continue;
                }

                String wxMerchantId = "unknown";
                Map<String, String> paramMap = extractKeyParam(logContent.split("验签字符串为:")[1].split("2020-")[0]);
                if (logContent.contains("<mch_id>")) {
                    wxMerchantId = logContent.split("<mch_id><!\\[CDATA\\[")[1].split("\\]\\]><")[0];
                }

                Map<String, String> confKeyParamMap = logContent.contains("current context confKey:") ?
                        extractConfKeyParam(logContent.split("current context confKey:")[1].split("2020-")[0])
                        : new HashMap<>();

                String reqWxAppId = logContent.contains("<appid><![CDATA[") ?
                        logContent.split("<appid><!\\[CDATA\\[")[1].split("\\]\\]></appid>")[0] : "";

                String totalKey = wxMerchantId + paramMap.toString();
                if (resultSet.contains(totalKey)) {
                    continue;
                } else {
                    resultSet.add(totalKey);
                    List<String> currentLine = new ArrayList<>();

                    currentLine.add(StringUtils.isBlank(paramMap.get("payType")) ? "" : paramMap.get("payType"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("payMode")) ? "" : paramMap.get("payMode"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("appName")) ? "" : paramMap.get("appName"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("appId")) ? "" : paramMap.get("appId"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("merchantId")) ? "" : paramMap.get("merchantId"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("subMerchantId")) ? "" : paramMap.get("subMerchantId"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("bizMerchantNo")) ? "" : paramMap.get("bizMerchantNo"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("bizSubMerchantNo")) ? "" : paramMap.get("bizSubMerchantNo"));

                    currentLine.add(StringUtils.isBlank(confKeyParamMap.get("payMode")) ? "" : confKeyParamMap.get("payMode"));
                    currentLine.add(StringUtils.isBlank(confKeyParamMap.get("appName")) ? "" : confKeyParamMap.get("appName"));
//                    currentLine.add(StringUtils.isBlank(confKeyParamMap.get("notifyKey")) ? "" : confKeyParamMap.get("notifyKey"));
                    currentLine.add(StringUtils.isBlank(confKeyParamMap.get("auxiliaryAttribute")) ? "" : confKeyParamMap.get("auxiliaryAttribute"));
                    currentLine.add(reqWxAppId);

                    currentLine.add(wxMerchantId);  //wxMerchantId
                    resultList.add(currentLine);
                }
            } catch (Exception ex) {
                System.out.println("Exception parse traceId: " + entry.getKey());
            }
        }

        String[] title = {"入参-payType", "入参-payMode", "入参-appName", "入参-appId", "入参-merchantId", "入参-subMerchantId",
                "入参-bizMerchantNo", "入参-bizSubMerchantNo", "中间参数-confKey-payMode", "中间参数-confKey-appName",
                "中间参数-confKey-auxiliaryAttribute", "输出参数-reqWxAppId", "输出参数-wxMerchantId"};
        //获取当前时间
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
        String date = df.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳
        //存储Excel的路径
        String path = "/Users/vonmax/Downloads/wxAnalysis_" + date + ".xlsx";
        createNewExcel(resultList, title, path);
    }


    private static void createExcel(ArrayList<String> list) {

        //获取当前时间
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
        String date = df.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳

        //存储路径--获取桌面位置
        FileSystemView view = FileSystemView.getFileSystemView();
        //存储Excel的路径
        String path = "/Users/vonmax/Downloads/" + date + ".xlsx";
        System.out.print("write to path :" + path);
        try {

            //定义一个Excel表格
            XSSFWorkbook wb = new XSSFWorkbook();  //创建工作薄
            XSSFSheet sheet = wb.createSheet("sheet1"); //创建工作表
            XSSFRow row = sheet.createRow(30); //行
            XSSFCell cell;  //单元格

            //添加表头数据
            for (int i = 0; i < list.size(); i++) {
                //从前端接受到的参数封装成list集合，然后遍历下标从而取出对应的值
                String value = list.get(i);
                //将取到的值依次写到Excel的第一行的cell中
                row.createCell(i).setCellValue(value);
            }

            //输出流,下载时候的位置
//            FileWriter outputStream1 = new FileWriter(path);
            FileOutputStream outputStream = new FileOutputStream(path);
            wb.write(outputStream);
            outputStream.flush();
            outputStream.close();
            System.out.println("写入成功");
        } catch (Exception e) {
            System.out.println("写入失败");
            e.printStackTrace();
        }
    }

    /**
     * 重新创建新Excel文件
     *
     * @return
     */
    public static String createNewExcel(List<List<String>> objList, String[] title, String filePath) {
        try {

            // 创建Excel的工作书册 Workbook,对应到一个excel文档
            XSSFWorkbook wb = new XSSFWorkbook();
            // 创建Excel的工作sheet,对应到一个excel文档的tab
            XSSFSheet sheet = wb.createSheet("sheet1");
            for (int i = 0; i < title.length; i++) {
                sheet.setColumnWidth(i, 4500);// 设置单元格宽度
            }

            XSSFRow firstRow = sheet.createRow(0);
            // 设置字体
            XSSFFont font = wb.createFont();
            font.setBold(true);// 粗体字
            font.setFontName("宋体");
            // 设置单元格属性
            CellStyle cellStyle = wb.createCellStyle();
            cellStyle.setFont(font);// 设置字体
//            cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//设置填充方案
//            cellStyle.setFillForegroundColor((short) 122); //设置填充颜色

            // 生成表头
            for (int i = 0; i < title.length; i++) {
                XSSFCell cell = firstRow.createCell(i);
                cell.setCellValue(title[i]);
                cell.setCellStyle(cellStyle);// 设置单元格背景
            }
            // 生成数据
            for (int i = 0; i < objList.size(); i++) {
                List<String> lineObj = objList.get(i);
                XSSFRow row = sheet.createRow(i + 1);// 因为表头已经占用了第一行，所以后面生成的行需从第二行开始
                try {

                    for (int j = 0; j < lineObj.size(); j++) {
                        XSSFCell cell = row.createCell(j);
                        cell.setCellValue(lineObj.get(j).toString());
                    }
                } catch (Exception e) {
                    System.out.println("write line exception: " + lineObj.toString());
                }
            }
            FileOutputStream os = new FileOutputStream(filePath);
            wb.write(os);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) throws Exception {
        run_analysis_wxMerchantId();
    }

}

